package com.hb.domain.user.service.impl;

import cn.hutool.core.lang.Validator;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.google.common.collect.Sets;
import com.hb.core.base.PageDataInfo;
import com.hb.core.base.PageFactory;
import com.hb.core.constant.Constants;
import com.hb.core.context.CurrentAccountHolder;
import com.hb.core.enums.CommCode;
import com.hb.core.exception.ServiceException;
import com.hb.core.model.SecurityClient;
import com.hb.domain.user.assembler.UserDoConvert;
import com.hb.domain.user.entity.UserDo;
import com.hb.domain.user.service.ISysUserService;
import com.hb.repository.SysUserRepository;
import com.hb.repository.entity.SysUser;
import com.hb.util.IdcardUtils;
import com.hb.vo.UserVO;
import com.hb.vo.request.UpdatePwdRequestVO;
import com.hb.vo.request.UserAddRequestVO;
import com.hb.vo.request.UserRequestVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;

/**
 * @description:
 * @projectName: zhb-frame-build
 * @author: zhouhaizhi
 * @createTime: 2021/8/11 17:10
 * @version:1.0
 */
@Service
public class SysUserServiceImpl implements ISysUserService {

    @Autowired
    private SysUserRepository sysUserRepository;

    @Autowired
    private UserDoConvert userDoConvert;

    @Override
    public PageDataInfo<UserVO> pageInfo(UserRequestVO userRequestVO) {
        IPage<SysUser> page = PageFactory.createPage(userRequestVO);
        if (null == page) {
            return PageDataInfo.EMPTY;
        }
        page = sysUserRepository.pageInfo(page, userRequestVO);

        List<UserVO> list = userDoConvert.toVoList(page.getRecords());
        return new PageDataInfo<UserVO>(list, page.getTotal(), (int) page.getPages());
    }

    @Override
    public List<UserVO> getUserAll() {
        List<UserVO> list = userDoConvert.toVoList(sysUserRepository.getUserAll());
        return list;
    }

    @Override
    public UserVO getByUserId(String userId) {
        return userDoConvert.toVo(sysUserRepository.getById(userId));
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void addUser(UserDo userDo) {
        //校验
        this.checkUser(userDo);
        SysUser sysUser = userDoConvert.toEntity(userDo);
        boolean result = sysUserRepository.save(sysUser);
        if (!result) {
            throw new ServiceException(CommCode.PARAM_ERROE);
        }
        // TODO 保存用户角色关联表
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateUser(UserDo userDo) {
        //校验
        this.checkUser(userDo);
        //更新
        userDo.update();
        SysUser sysUser = userDoConvert.toEntity(userDo);
        sysUserRepository.updateById(sysUser);
        // TODO 移除旧角色 插入新角色
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteUser(String userId) {
        if (Constants.SUPER_USER_ID.equals(userId)) {
            throw new ServiceException(CommCode.PARAM_ERROE, "禁止对超级用户进行删除");
        }
        sysUserRepository.removeById(userId);
        // TODO 删除角色相关信息
    }

    /**
     * @描述 获取登录账户的信息
     * @创建人 zhouhaizhi
     * @创建时间 2021/8/27 14:46
     * @参数
     * @返回值
     * @修改人和其它信息
     */
    @Override
    public SecurityClient getSecurityClientByLoginName(String loginName) {
        SysUser user = sysUserRepository.getUserByLoginName(loginName);
        if (Objects.isNull(user)) {
            return null;
        }
        SecurityClient securityClient = new SecurityClient();
        securityClient.setId(user.getId())
                .setClientId(user.getLoginName())
                .setPassword(user.getPassword())
                .setUsername(user.getName())
                .setAud(Sets.newHashSet(Constants.APP_NAME))
                .setInvalid(user.getEnabled().equals(Constants.Flag.IS_FLASE));
        //TODO 设置角色id
        securityClient.setRoleIds(Sets.newHashSet());
        //TODO 设置资源权限
        securityClient.setAuthorities(Sets.newHashSet());
        return securityClient;
    }

    @Override
    public void updatePassword(UpdatePwdRequestVO updatePwdRequestVO) {
        //当前登录密码
        String loginPassword = CurrentAccountHolder.get().getPassword();
        //获取旧密码
        String password = SecureUtil.md5(updatePwdRequestVO.getOldPassword());
        if (!loginPassword.equals(password)) {
            throw new ServiceException(CommCode.PARAM_ERROE, "旧密码输入错误！");
        }
        if (updatePwdRequestVO.getOldPassword().equals(updatePwdRequestVO.getNewPassword())) {
            throw new ServiceException(CommCode.PARAM_ERROE, "新密码和旧密码不能相同！");
        }
        SysUser sysUser = new SysUser();
        sysUser.setId(CurrentAccountHolder.get().getId());
        sysUser.setPassword(SecureUtil.md5(updatePwdRequestVO.getNewPassword()));
        sysUserRepository.updateById(sysUser);
    }

    /**
     * @描述 校验身份信息
     * @创建人 zhouhaizhi
     * @创建时间 2021/9/2 11:13
     * @参数
     * @返回值
     * @修改人和其它信息
     */
    public void checkUser(UserDo userDo) {
        SysUser sysUser = sysUserRepository.getUserByLoginName(userDo.getLoginName());
        if (!Objects.isNull(sysUser)) {
            throw new ServiceException(CommCode.PARAM_ERROE, "存在相同的登录用户");
        }
        if (StringUtils.isNotBlank(userDo.getIdCard()) && IdcardUtils.validateCard(userDo.getIdCard())) {
            throw new ServiceException(CommCode.PARAM_ERROE, "身份正有误");
        }
        if (StringUtils.isNotEmpty(userDo.getEmail()) && !Validator.isEmail(userDo.getEmail())) {
            throw new ServiceException(CommCode.PARAM_ERROE, "邮箱有误");
        }
    }
}
